package com.feishi.core.util.bitbyte.dbc;

import com.feishi.core.util.common.StringUtil;
import lombok.Data;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@Data
public class DBCConfig {
    private String version;
    private int baudRate;
    private List<String> newSymbols=new ArrayList<>();
    private List<String> bUnit=new ArrayList<>();
    private List<DBCMsg> dbcMsgs=new ArrayList<>();

    private int readStatus=0;
    private DBCMsg currentMsg;
    private String comment;
    public void readLine(String line){
        if(line.replaceAll("\\s+","").equals("")){
            return;
        }
        if(readStatus==0){
            if(line.startsWith(DBCDefine.VERSION)){
                version=line.substring(DBCDefine.VERSION.length()).trim().replaceAll("^\"","").replaceAll("\"$","");
                System.out.println(version);
            }else if(line.startsWith(DBCDefine.NewSymbol)){
                readStatus=1;
            }else if(line.startsWith(DBCDefine.BaudRate)){
                baudRate=line.split(":").length==2?Integer.parseInt(line.split(":")[1]):-1;
            }else if(line.startsWith(DBCDefine.BUnit)){
                bUnit= Arrays.asList(line.split(":")[1].trim().split(" "));
            }else if(line.startsWith(DBCDefine.BO_)){
                currentMsg=new DBCMsg(line);
                readStatus=2;
                dbcMsgs.add(currentMsg);
            }else if(line.startsWith(DBCDefine.CM_)){
                comment="";
                readStatus=3;
                readLine(line);
            }else if(line.startsWith(DBCDefine.BA_DEF_+" ")){
                addDef(line);
            }else if(line.startsWith(DBCDefine.BA_DEF_DEF_+" ")){
                addDefdef(line);
            }else if(line.startsWith(DBCDefine.BA_)){
                addba(line);
            }else if(line.startsWith(DBCDefine.VAL_)){
                addVal(line);
            }
        }else if(readStatus==1) {
            if(line.startsWith("\t")){
                newSymbols.add(line.trim());
            }else {
                readStatus=0;
                readLine(line);
            }
        }else if(readStatus==2) {
            if(!currentMsg.readLine(line)){
                readStatus=0;
                readLine(line);
            }
        }else if(readStatus==3) {
            comment+=("".equals(comment)?"":"\n")+line;

            if(comment.endsWith("\";")){
                regComment(comment);
                readStatus=0;
            }
        }
        System.out.println(line);
    }
    //VAL_ 881 BCM_ReverseLightSts 1 "ON" 0 "OFF" ;
    private List<List<String>> valList=new ArrayList<>();
    private void addVal(String line) {

        String match="VAL_ ([^ ]+) ([^ ]+) ((([^ ]+) )+);";
        if(!matchTolist(line,match,valList)){
            System.err.println(111);
        };
    }

    //BA_ "GenSigInvalidValue" SG_ 834 Checksum_0x342 0;
    private List<List<String>> baList=new ArrayList<>();
    private void addba(String line) {
        String match="BA_\\s+\"([^\"]+)\"\\s+([^ ]+)\\s+([^ ]+)\\s+([^;]+);";
        if(!matchTolist(line,match,baList)){
            System.err.println(111);
        };
    }

    //BA_DEF_DEF_  "GenSigStartValue" 0;
    private void addDefdef(String line) {
        String match="BA_DEF_DEF_\\s+\"([^\"]+)\"\\s+([^;]+);";
        if(!matchTolist(line,match,defdef)){
            System.err.println(111);
        };
    }

    private boolean matchTolist(String line, String match, List<List<String>> out) {
        List<String> list = StringUtil.matchAll(match, line);
        if(list!=null){
            out.add(list);
            return true;
        }
        return false;
    }

    //BA_DEF_ SG_  "GenSigStartValue" INT 0 0;
    private void addDef(String line) {
        String match="^BA_DEF_\\s?([^\\s]+)?\\s+\"([^\"]+)\"\\s+(" +
                "((INT)\\s+([^\\s]+)\\s+([^;]+))" +
                "|((ENUM)\\s+([^;]+))" +
                "|((STRING)\\s+)" +
                ");";
        if(!matchTolist(line,match,def)){
            System.err.println(111);
        };
    }

    private List<List<String>> signalsComments=new ArrayList<>();
    private List<List<String>> def=new ArrayList<>();
    private List<List<String>> defdef=new ArrayList<>();
    private void regComment(String comment) {
        List<String> list = StringUtil.matchAll("^CM_ SG_ (\\d+) ([^ ]+) \"([^\"]+)\";", comment);
        if(list.size()>0){
            DBCMsg dbcMsg = this.dbcMsgs.stream().filter(d -> Integer.parseInt(list.get(0)) == d.getId()).findFirst().get();
            DBCSignal signals = dbcMsg.getDbcSignals().stream().filter(d -> d.getSignalName().equals(list.get(1))).findFirst().get();
            signalsComments.add(list);
            System.out.println(list);
            return;
        }
        System.err.println(1);
    }

    ;
}
